
package GUI;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import javax.swing.JPanel;

public class Controle extends JPanel implements Runnable {

    private Obstaculos obstaculos = new Obstaculos();
    private Agente eve = new Agente();

    private int fator_de_escala = 3;
    private boolean expandir = false;
    private boolean start = false;
    private Point posicao = new Point(0, 0);    
    private int unidadeDeArea = 5;
    boolean pontos = false;
    int[] ptsOrigem = {-10,-10};
    int[] ptsDestino = {-10,-10};
    public ArrayList <Point> linha, caminho, grafo, menorCaminho;
    public int grid = 0;
    public int tempGrafo, tempCaminho, tempObstaculo, tempGrid;

    public Controle()
    {
        linha = new ArrayList<Point>();
        caminho = new ArrayList<Point>();
        grafo = new ArrayList<Point>();
        menorCaminho = new ArrayList<Point>();

        tempGrafo = tempCaminho = tempObstaculo = tempGrid = 0;

        desenhaArena();

        Thread t = new Thread(this, "TELA");
        setVisible(true);
        t.start();
    }

    @Override
    public void paint(Graphics g)
    {
        super.paint(g);

        // Para a escolha do grid a ser desenhado no labirinto
        switch (grid)
        {
            case 0:
                 obstaculos.desenhaGrig(g, unidadeDeArea);
                 break;
            case 1:
                 obstaculos.desenhaGrig1(g, unidadeDeArea);
                 break;
            case 2:
                 obstaculos.desenhaGrig2(g, unidadeDeArea);
                 break;
            case 3:
                 obstaculos.desenhaGrig3(g, unidadeDeArea);
                 break;
        }

        desenhaLinha(g);
        desenhaGrafo(g);
        desenhaMenorCaminho(g);

        if(tempObstaculo == 0)
        {
            if (expandir)
            {
                obstaculos.desenhaExpandido((Graphics2D) g);
            }
            obstaculos.desenhaObstaculos(g);
        }

        // Desenha a posiçao inicial e final do robo
        if (pontos)
        {
            g.setColor(Color.WHITE);
            g.drawString("ORIGEM", ptsOrigem[0]+10, ptsOrigem[1]+10);
            eve.desenhaAgente((Graphics2D) g, ptsOrigem[0], ptsOrigem[1], this);
            g.drawString("DESTINO", ptsDestino[0]+10, ptsDestino[1]+10);
            g.setColor(Color.BLUE);
            g.fillOval(ptsDestino[0], ptsDestino[1], 10, 10);
        }
    }

    public void desenhaArena()
    {
        addObstArena(40, 40, 48.5, 1);
        addObstArena(40, 128.5, 48.5, 1);

        addObstArena(40, 88.5, 1, 33.5);
        addObstArena(40, 128.5, 1, 33.5);

        addObstArena(81.5, 88.5, 1, 104);
        addObstArena(81.5, 128.5, 1, 104);

        addObstArena(112, 0, 40, 1);
        addObstArena(112, 180, 40, 1);

        addObstArena(152, 0, 40, 1);
        addObstArena(152, 180, 40, 1);

        addObstArena(230, 40, 48.5, 1);
        addObstArena(230, 128.5, 48.5, 1);

        addObstArena(196.5, 88.5, 1, 33.5);
        addObstArena(196.5, 128.5, 1, 33.5);
    }

    public void addObstArena(double x, double y, double altura, double largura)
    {
        addObstaculos((int)(fator_de_escala*x), (int)(fator_de_escala*y), (int)(fator_de_escala*altura), (int)(fator_de_escala*largura));
    }

    public void limparCampo()
    {
        linha.clear();
        caminho.clear();
        grafo.clear();
        menorCaminho.clear();
        obstaculos.limparCampo();
        posicao.x = 0;
        posicao.y = 0;
        pontos = false;
        desenhaArena();
        super.repaint();
    }

    public void desenhaGridObstaculos1()
    {
        grid = 1;
        super.repaint();
    }

    public void desenhaGridObstaculos2()
    {
        grid = 2;
        super.repaint();
    }

    public void desenhaGridObstaculos3()
    {
        grid = 3;
        super.repaint();
    }

    public void run()
    {
        while (true) {
            super.repaint();
        }
    }

    public void addObstaculos(int x, int y, int tipo, boolean rotacionar, int angulo)
    {
        obstaculos.addObstaculos(x, y, tipo, rotacionar, angulo);
        super.repaint();
    }

    public void addObstaculos(int x, int y, int altura, int largura)
    {
        obstaculos.addObstaculos(x, y, altura, largura);
        super.repaint();
    }

    public void setPontos(boolean pontos)
    {
        this.pontos = pontos;
    }

    public void setPtsOrigem(int x, int y)
    {
        this.ptsOrigem[0]=x;
        this.ptsOrigem[1]=y;
    }

    public void setPtsDestino(int x, int y)
    {
        this.ptsDestino[0]=x;
        this.ptsDestino[1]=y;
    }

    public int[] getPtsDestino()
    {
        return ptsDestino;
    }

    public int[] getPtsOrigem()
    {
        return ptsOrigem;
    }

    public void setStart(boolean start) {
        this.start = start;
    }

    public void setPosicao(Point posicao) {
        this.posicao = posicao;
        super.repaint();
    }

    public Point getPosicao() {
        return posicao;
    }

    public boolean isExpandir() {
        return expandir;
    }

    public void setExpandir(boolean expandir) {
        this.expandir = expandir;
    }

    public Obstaculos getObstaculos() {
        return obstaculos;
    }

    public void setObstaculos(Obstaculos obstaculos) {
        this.obstaculos = obstaculos;
    }

    public void setaLinha(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
    {
        linha.add(new Point (x1, y1));
        linha.add(new Point (x2, y2));
        linha.add(new Point (x3, y3));
        linha.add(new Point (x4, y4));
    }

    public void setaLinhaCaminho(int x1, int y1, int x2, int y2)
    {
        caminho.add(new Point (x1, y1));
        caminho.add(new Point (x2, y2));
    }

    public void setaLinhaMelhorCaminho(int x1, int y1, int x2, int y2)
    {
        menorCaminho.add(new Point (x1, y1));
        menorCaminho.add(new Point (x2, y2));
    }

    public void setaLinhaGrafo(int x1, int y1, int x2, int y2)
    {
        grafo.add(new Point (x1, y1));
        grafo.add(new Point (x2, y2));
    }

    public void desenhaLinha(Graphics g)
    {
        if(tempGrid == 0)
        {
            if(!linha.isEmpty())
            {
                for(int i = 0; i < linha.size()-1; i++)
                {
                    Point p = linha.get(i);
                    i++;
                    Point p2 = linha.get(i);

                    g.setColor(Color.RED);
                    g.drawLine(p.x, p.y, p2.x, p2.y);
                    super.repaint();
                }
            }
        }
    }

    public void desenhaMenorCaminho(Graphics g)
    {
        if(tempCaminho == 0)
        {
            if(!menorCaminho.isEmpty())
            {
                menorCaminho.get(0).setLocation(new Point(ptsOrigem[0], ptsOrigem[1]));
                menorCaminho.get(menorCaminho.size()-1).setLocation(new Point(ptsDestino[0], ptsDestino[1]));

                for(int i = 0; i < menorCaminho.size()-1; i++)
                {
                    Point p = menorCaminho.get(i);
                    i++;
                    Point p2 = menorCaminho.get(i);

                    g.setColor(Color.ORANGE);
                    g.drawLine(p.x, p.y, p2.x, p2.y);
                    super.repaint();
                }
            }
        }
    }


    public void desenhaGrafo(Graphics g)
    {
        if(tempGrafo != 0)
        {
            if(!grafo.isEmpty())
            {
                for(int i = 0; i < grafo.size()-1; i++)
                {
                    Point p = grafo.get(i);
                    i++;
                    Point p2 = grafo.get(i);

                    g.setColor(Color.LIGHT_GRAY);
                    g.drawLine(p.x, p.y, p2.x, p2.y);
                    super.repaint();
                }
            }
        }
    }
}
